<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue</title>
</head>
<body>
<div id="app">
    <h1>{{ count }}</h1>
    <button @click="increment">+</button>
</div>

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex@3.5.1/dist/vuex.js"></script>
<script>
    // 声明状态管理机
    const store = new Vuex.Store({
        state: {
            count: 0
        },
        mutations: {
            // mutations里的修改方法必须是同步的，不可以异步实现
            increment(state) {
                state.count ++;
            },
            increment2(state, n) {
                state.count += n;
            },
        },
        // actions与mutations区别：
        // 1. mutations 的操作只能是同步的, 可以认为是原子的同步方法
        // 2. actions 里的方法同步异步都可以，可以直接代替mutations修改state
        actions: {
            // context参数是上下文不是store本身，通过context.commit调用mutations方法
            // 通过context.state 获取状态，context.getters获取getter方法，context.dispatch调用其他action方法
            increment(context) {
                console.log('action invoked.');
                setTimeout(() => {
                    console.log('timeout executed.');
                    context.commit('increment');
                }, 1000);
            },
            // 上面的简写形式， 如果用到commit state则：{commit, state}， 方法内直接使用不需要使用context
            // increment({commit}) {
            //     // 直接调用commit即可
            //     commit('increment');
            // },
            increment2(context, payload) {
                setTimeout(() => {
                    console.log('timeout executed2.');
                    context.commit('increment2', payload.n);
                }, 1000);
            },
            increment3(context, payload) {
                // 返回promise对象，异步执行
                return new Promise((resolve, reject) => {
                    console.log('promise executed.');
                    context.commit('increment2', payload.n);
                });
            }
        }
    });

    let vm = new Vue({
        el: "#app",
        data: {
            count: 0,
        },
        methods: {
            increment() {
                // 调用action方法
                // 之所以出现action，是因为mutations不支持异步，而action可以
                this.$store.dispatch('increment');

                // 用法与commit的传参用法相同
                if (this.count % 2 === 0) {
                    this.$store.dispatch('increment2', {
                        n: 100
                    });
                }

                // 获取异步执行结果
                this.$store.dispatch('increment3', {n: 200}).then(() => {
                    console.log('promise callback.')
                });

                // console.log(this.$store.state.count);
                this.count = this.$store.state.count;
            }
        },
        // 注入状态管理器
        store: store
    });
</script>
</body>
</html>
